Aller au contenu

Utilisateur:Sub/brouillons/Web scraping

Un livre de Wikilivres.

Wikipédia propose un article sur : « Web scraping ».

Le « Web scraping » ou « Web harvesting » (littéralement « récolte Web ») désigne l'extraction automatique de contenus disponibles via le Web.

À quoi ça peut servir ?

[modifier | modifier le wikicode]

On peut se demander à quoi peut servir d'extraire une information disponible via le Web. Voici plusieurs applications dans ce domaine.

Extraire des données pour les sémantiser

[modifier | modifier le wikicode]

La plupart des sites Web proposent de consulter des données via le navigateur. De nombreux sites Web proposent leurs données uniquement via des pages Web lisibles par un humain dans un navigateur mais ne proposent pas ces données de façon structurées, interprétables. C'est notamment le cas de tous les sites Web qui ne sont pas encore passés au Web sémantique. Pour corriger cela, l'extraction du contenu puis sa sémantisation peut se révéler utile. Exemples de projets :

  • DBpedia est une base de données sémantique dont tout le contenu est extrait de Wikipédia. DBpedia propose donc une partie du contenu de Wikipédia sous forme structurée et sémantisée. Cela permet de faire des requêtes complexes (par exemple, les joueurs de football qui portent un maillot numéroté 11 dans un club ayant un stade de plus de 40 000 places dans un pays de plus de 10 millions d'habitants), ce que ne permet pas le moteur de recherche de Wikipédia.

Extraire des données pour pouvoir les traiter

[modifier | modifier le wikicode]

De façon similaire, il ne vous sera pas possible de traiter des données présentées sur une page Web (les trier, en faire des statistiques). Pourtant, lorsqu'on doit consulter de grands ensembles de données, on voudrait bien pouvoir extraire toutes ces données pour pouvoir les entrer dans un logiciel permettant de les manipuler aisément (typiquement, un tableur ou une base de données). Exemples :

  • Extraire des données d'un site pour pouvoir les charger dans une bases de données afin de mener des études statistiques (data-mining)
  • Extraire les petites annonces d'un site pour pouvoir les charger dans un logiciel tableur (OpenOffice.org Calc ou Microsoft Excel) et ainsi pouvoir calculer au mieux son investissement.

Extraire du contenu pour pouvoir le consulter hors-ligne

[modifier | modifier le wikicode]

Exemples :

  • Extraire des vidéos d'une plate-forme de vidéos en ligne pour pouvoir les consulter sur un lecteur multimédia portable
  • Extraire toutes les images d'une galerie photo pour pouvoir les visionner sur un cadre photo numérique

Extraire le contenu pour en changer le format ou la forme

[modifier | modifier le wikicode]

Exemples :

  • Générer un flux RSS ou Atom pour un site qui en est dépourvu à partir de données extraites regulièrement.
  • Extraire les informations d'un site événementiel ou d'un emploi du temps en ligne pour les transformer au format hCalendar afin de pouvoir facilement les charger dans un assistant personnel ou un logiciel de calendrier (comme Mozilla Sunbird).
  • Extraire des vidéos Flash pour les transcoder dans un format lisible sur une plate-forme qui ne supporte pas flash
  • Visualiser la discographie de différents groupe de rocks sur une frise chronologique (les données sont fournies par DBpedia, qui extrait les données depuis Wikipédia)
  • Extraire une page web inaccessible (aux personnes handicapées) pour en créer une version similaire mais accessible.

Sauvegarder et restaurer ses données

[modifier | modifier le wikicode]

L'avènement du cloud computing (et, conséquemment, celle du Software as a service) marque une tendance, chez de nombreux internautes, à ne plus stocker ses données sur son ordinateur (vidéos, marque-pages, playlists de musique, courriels et autres fichiers) et à utiliser, à la place, des plate-formes en ligne. Cette solution est attrayante mais elle a aussi ses inconvénients. Parmi eux, celui de la conservation de ces données.

Si vous pensez que vos données sont en sécurité sur Internet, vous vous trompez. Les entreprises ne sont pas à l'abri des problèmes et menaces variés (technique, crapuleuse, juridique…) qui peuvent survenir quand on gère un site Web. Voici quelques exemples parmi tant d'autres :

  • Fin janvier 2009, un célèbre site d'enregistrement et de partage de liens subit une panne. Le site ne propose plus qu'à ses visiteurs, venus chercher les marque-pages qu'ils enregistrent et consultent quotidiennement là-bas, une simple page expliquant que leurs données sont perdues et en cours de récupération. Une semaine plus tard, la même page explique que les données n'ont pu être restaurées, et qu'il ne reste aux usagers du services que les excuses du responsable du site et... son invitation à utiliser un service concurrent !
  • Mai 2008 : un site qui regroupe les passionnés de la photo voit la plate-forme qui hébergeait les photoblogs des participants (quelques 2200 blogs…) piratée. Suite à l'annonce du problème sur le forum du site, les réactions ne se sont pas faites attendre : « ouais, super, et les quelques dizaines d'heures que j'avais passé dessus??? Vraiment sympa... Et bien moi je laisse tomber, pas la peine de garder mon compte, salut! »[1].
  • Suite au décret d'une loi française, le site WikiP2P a fermé immédiatement sans laisser le temps aux contributeurs (pourtant les seuls à fournir le site en contenu) récupérer tout ou partie du contenu qu'ils avaient élaboré de concert.

Dans tous ces cas, les personnes concernées ont perdu une quantité importante de données.

À l'inverse, vous pourriez perdre des données qui se trouve sur votre machine (marque-pages, photos) et vous souhaiteriez en restaurer une partie en rapatriant celles que vous avez publié sur le Web.

Exemples :

  • Sauvegarder tous les articles de votre blog pour pouvoir les restaurer ou les importer sur un autre blog
  • Sauvegarder les photos que vous avez publiées sur le Web après avoir perdu les fichiers originaux (panne informatique)

Archiver des données

[modifier | modifier le wikicode]

Le Web est un média particulièrement versatile. Rien ne garantie qu'une donnée disponible à un instant donné soit toujours disponible plus tard. Exemples :

  • Sur Wikipédia, chaque référence vers une page Web est accompagnée d'un lien cache qui permet d'accéder à une version archivée de la page en question
    Wikipédia, l'encyclopédie étant soucieuse de la vérifiabilité de son contenu, toutes les pages Web qui servent de référence sont conservées dans un système de cache. Ainsi, l'information est toujours vérifiable même si l'article qui appuyait le propos a disparu du Web.
  • La transition de la presse du papier vers le Web, qu'il s'agisse de grands quotidiens ou de la presse spécialisée, laisse sur place les bibliothécaires et archivistes qui doivent s'adapter. On peut souhaiter archiver régulièrement des pages afin de constituer un fond documentaire.
  • Archiver une vidéo afin de s'assurer qu'elle sera toujours disponible pour nous, en particulier ci on craint qu'elle soit effacée de la plate-forme où elle a été publiée dans les plus brefs délais.

Les données extraites peuvent servir de base à des contenus plus ou moins originaux. Exemples :

  • Catfishing est un jeu de quizz, il faut deviner un mot ou un nom à partir des catégories auxquelles il appartient pour gagner des points. En fait, le jeu choisit un article de Wikipédia au hasard et donne les catégories auxquelles il appartient, le joueur doit deviner le titre de l'article.
  • LiveJournal Dungeon Adventure est un jeu d'aventure dans un donjon (dans la droite lignée des porte-monstre-trésors). Pour commencer la partie, il faut donner l'adresse de son blog et le jeu extrait des données sur vos amis et vos passions pour les prendre en compte dans la génération du donjon. Les monstres de cet univers portent les noms de vos amis et les trésors à découvrir sont des objets inspirés de vos goûts.
  • Tous les moteurs de recherches fonctionne en effectuant des recherches dans un index constitués à partir de données recueillies en amont par un programme qui parcoure le Web pour en indexer le contenu. Ces programmes, appelés « robot d'indexation », extraient des pages qu'ils trouvent titres, textes, mot-clés, liens (qui permettent de continuer l'exploration) et toutes informations susceptibles d'évaluer la page selon les critères de recherches souhaités. Pour cela, ils font appels aux techniques de Web scraping.
  • L'extraction de données de différents sites pour les croiser combinée à l'utilisation d'API diverses peut donner des mashup (ou application composite). C'est ainsi que fonctionne de nombreux moteurs de recherches BitTorrent ou les comparateurs de prix qui, lorsque vous faites une recherche, lancent cette même recherche sur différents sites, extraient puis synthétisent les résultats.

Pour simuler le comportement d'un internaute

[modifier | modifier le wikicode]
  • Tester un site web
  • Créer un bot pour un jeu par navigateur afin de le tester (au cours de son développement). Il peut aussi s'agir de remplacer un joueur humain afin d'automatiser des tâches pénibles ou de jouer pendant l'absence momentanée d'un joueur.
  • Créer des clients pour les sites d'hébergement de fichiers pour télécharger automatiquement depuis ces plate-formes (exemples : Tucan Manager, JDownloader).

Avant d'aller plus loin…

[modifier | modifier le wikicode]

Quels sont les pré-requis pour lire ce livre ?

[modifier | modifier le wikicode]

Quelques considérations diverses

[modifier | modifier le wikicode]

À propos de Mozilla Firefox

[modifier | modifier le wikicode]

Tout au long de l'ouvrage, nous allons nous appuyer sur le navigateur Mozilla Firefox. Si vous ne l'utilisez pas déjà (ce serai dommage...), vous pouvez obtenir et installer ce logiciel Libre en le téléchargeant gratuitement depuis le site officiel.

Firefox est facilement extensible. Dans la suite, nous ferons appel à plusieurs extensions pour remplir différentes tâches. Comme nous en installerons plusieurs, nous vous invitons à utiliser le gestionnaire de profils de Firefox. En effet, les nombreuses extensions que nous allons installer vont peut-être encombré votre navigation habituelle, aussi nous pouvons prévenir ce désagrément simplement si vous vous y prenez dès le début. Créez donc un profil « Web Scraping » dans Firefox : il sera consacré à vos activités de Web Scraping. Il vous suffira de revenir à votre profil habituel quand vous voudrez alléger votre navigation.

Vous êtes tout à fait libre d'utiliser un autre navigateur que Firefox, mais il faudra vous adapter en conséquence :

  • Opera, accompagné de quelques extensions[2], est à la hauteur.
  • Internet Explorer est, soyons clair, tout à fait incapable d'accomplir le dixième de ce qui est expliqué ici.

Légalité et légitimité

[modifier | modifier le wikicode]
  • Des outils simples
    • Pour extraire des vidéos
    • Pour télécharger en masse
    • Utiliser des scraping scripts
  • Créer vos propres scrapers
    • …avec XML
    • …avec Web Harvest
    • …avec un langage de scripts (PHP, Python, Perl)
      • Utiliser des langages de scripts (PHP, Python, Perl)
      • Récupérer le contenu
      • Analyser le contenu
      • Créer de bons scripts

à ajouter : web sémantique (SIMILE)

Télécharger en masse

[modifier | modifier le wikicode]

DownThemAll! est une extension Firefox que vous pouvez installer à partir de Mozilla addons.

Extraire des vidéos

[modifier | modifier le wikicode]

Les vidéos embarquées

[modifier | modifier le wikicode]

Avec Firefox : dans le menu « outils », sélectionnez « Informations sur la page ». Dans le panneau qui s'ouvre, sélectionnez l'onglet « Médias ». La liste, en haut du panneau représente tous les contenus qui sont inclus dans la page. Observez la colonne « Type » et cherchez les lignes de type « Embarqué » : s'il s'agit bien de la vidéo que vous voulez, vous avez trouvez ! Il ne vous reste plus qu'à cliquer sur le bouton « Enregistrer sous... ».

xVideoServiceThief

[modifier | modifier le wikicode]

xVideoServiceThief est un logiciel qui vous permet d'extraire des vidéos Flash de plus d'une cinquantaine de plate-formes de vidéos en ligne. Il est libre, gratuit et disponible en français.

De plus, xVSF intègre un convertisseur qui vous permettra de convertir vous vidéos dès qu'elles seront téléchargés dans le format que vous souhaitez.

Vous ne devriez avoir aucun mal à l'utiliser, il est très intuitif. Allez faire un tour dans les préférences, quelques options peuvent vous intéressé. Enfin, jeter un œil à ce petit bouton qui permet d'ouvrir une fenêtre « Glisser & Déposer », il s'agit d'une petite fenêtre panier à garder à côté de celle de votre navigateur dans laquelle il suffira de glisser puis déposer une ou plusieurs URL pour lancer automatiquement le téléchargement.

La solution que nous allons présenter maintenant peut être une solution si xVideoServiceThief échoue ou si le site n'est pas prit en charge. Nous présentons ici une solution qui est censé fonctionner sur presque la totalité des sites qui incorporent des lecteurs vidéos Flash.

Nous allons faire appel à Firebug, une extension Firefox. Vous pouvez l'installer à partir de Mozilla Addons. Une fois installée, ouvrez le panneau Firebug. En chargeant la page qui comporte la vidéo, le panneau devrait se remplir d'informations.

Examinez le contenu du panneau lorsque vous sélectionnez les onglets « Réseau » et « Tout ». Il s'agit là de toutes les requêtes qui ont été effectuées par votre navigateur pour obtenir toutes les données qui compose la page. Lancez la lecture de la vidéo, quelques lignes devraient s'ajouter dans la liste.

La réponse est dans l'une de ces lignes : au bout d'une de ces adresses se trouve le fichier vidéo. Passez les toute en revue : notamment, voici quelques critères qui devraient vous mettre sur la voie :

  • Si l'URL de destination pointe vers un fichier .flv ou .on2, il est possible que ce soit la bonne
  • Si la taille des données est significativement plus grande que toutes les autres, il est possible que ce soit la bone
  • Si le code de la requête est 30x (par exemple 302 ou 304), il s'agit d'une redirection. Il est possible que ce soit derrière cette adresse que se cache la vidéo. Copiez l'adresse (clic droit) et collez-la dans la barre de navigation. Rendez-vous à cette nouvelle adresse et inspectez à nouveau les informations que donne Firebug.

Une fois que vous avez trouver une adresse susceptible d'être la bonne, copiez-là (clic droit puis « ») et collez-la dans la barre de navigation. Si vous obtenez une fenêtre vous proposant le téléchargement, c'est très certainement gagné.

Récupérer des flux (streaming)

[modifier | modifier le wikicode]

Récupérer des vidéos diffusées en flux dans le navigateur n'est pas possible directement. Analyser la source de la page ou demandez votre lecteur embarqué (un clic droit sur la vidéo ?) de vous donner l'adresse du flux. Typiquement, les adresses de flux peuvent être reconnues par le protocole utilisé : si l'adresse débute par mms://, rtsp:// ou rtp://, vous avez bien à faire à un flux.

Utilisez alors un lecteur vidéo externe (comme VLC) pour ouvrir votre vidéo. Si elle se lit bien dans votre lecteur externe, vous êtes en bonne voix. Demandez-lui de sauvegarder le flux.

Remarquons que certaines adresses de flux commencent par http://, il peut effectivement s'agir d'un flux (vérifiez en essayant de l'ouvrir avec votre lecteur vidéo) mais il peut aussi y avoir au bout de cette URL un fichier très petit. Téléchargez-le puis ouvrez-le avec un éditeur de texte (au besoin, changez l'extension en .txt). Dans ce fichier texte, vous devriez pouvoir trouver l'adresse effective du flux.

VLC est un très bon lecteur vidéo. Il est aussi capable de sauvegarder un flux brut ou de le transcoder à la volée.

VLC est un excellent lecteur vidéo libre, multi-plateforme, gratuit et disponible en français. En plus de permettre la lecture d'un grand nombre de formats de fichiers vidéos (il en existe pléthore), il permet aussi de les convertir dès lors qu'on lui fournit les codecs adéquats. Enfin, il n'est pas seulement capable de lire des fichiers mais prend aussi en charge les flux et ce, selon de nombreux protocoles de streaming.

Dans VLC, ouvrez le menu « Média » puis sélectionnez « Convertir / Sauvegarder ». Sélectionnez l'onglet « Flux » et entrez l'adresse du flux. Cliquez sur « Convertir / Sauvegarder », une boîte de dialogue vous demandera de choisir les formats et les caractéristiques du fichier de sortie. Faites attention car VLC ne vérifiera pas vos réglages, aussi faites plusieurs essais et vérifiez systématiquement la qualité du résultat (le son notamment).

Pour utiliser VLC avec la ligne de commande, vous pouvez consulter la section consacrée du manuel.

Vérifiez que mplayer arrive à bien lire le flux :

mplayer <URL du flux à sauvegarder>

Si la vidéo s'affiche avec image et son corrects, vous pouvez sauvegarder le flux en ajouter l'option -dumpstream :

mplayer -dumpstream <URL du flux à sauvegarder>

Il n'y a plus qu'à attendre que la vidéo soit lue entièrement. Un fichier stream.dump devrait apparaître.

Utiliser des scripts

[modifier | modifier le wikicode]

Bien qu'ils proposent souvent une interface austère, les scripts peuvent être parfaitement efficaces. Les scripts sont spécifiques à un site et remplissent une tâche bien précise. À vous donc de trouver sur la Toile le script qui correspond à vos attentes… s'il existe. Nous allons d'abord voir comment utiliser les scripts, puis nous vous donnerons quelques bons scripts.

Comment utiliser les scripts ?

[modifier | modifier le wikicode]

Pour lancer un script, vous devez disposer de l'interpréteur du langage dans lequel il est écrit. Pour un script Python, il faut installer l'interpréteur Python, etc. Les interpréteurs sont des programmes qui s'installent comme les autres. Cela dépend donc de votre système d'exploitation.

Paquet logiciel

Sous Linux, la plupart sera déjà installés, vous n'avez rien à faire. Dans le cas contraire, installer quelques paquets suffira.

Vous devrez télécharger et installer un à un les interpréteurs dont vous avez besoin. Vous pourrez obtenir les fichiers d'installation sur les sites officiels de ces projets qui les distribuent librement et gratuitement.

Quelques scripts

[modifier | modifier le wikicode]

ajoutez les vôtres !

Arte +7 recorder

[modifier | modifier le wikicode]

Arte +7 recorder permet de lister et de télécharger les vidéos disponibles sur la plate-forme arte +7. Il s'agit d'un script bash.

FreeTP est un client pour le service d'hébergement en un clic dl.free.fr. C'est un script Python avec une interface graphique.

Youtube-dl est un script Python pour extraire des vidéos YouTube.

  • Le format flv d'origine est conservé.
  • Gère l'identification si elle est demandée pour visionner la vidéo.
  • Il existe une interface graphique appelée PyTube
  • Il est disponible dans certains dépôt linux mais attention, la version est souvent trop vieille pour fonctionner. Il vaut mieux utiliser la toute dernière version disponible sur le site.

Yahoo Group Archiver

[modifier | modifier le wikicode]

Yahoo Group Archiver est un ensemble de scripts Perl pour archiver des Yahoo! Groups.

  • Quatre scripts pour télécharger messages, fichiers, photos et membres.
  • Possibilité d'obtenir la liste des membres au format Excel.
  • Sous ubuntu, vous devez installer le paquet libterm-readkey-perl
  • Il semble que le script téléchargeant les photos soit bugué : il ne télécharge que la première page. un patch est disponible.

Utiliser les langages de scripts

[modifier | modifier le wikicode]

Les langages de scripts sont tout à fait adéquats pour écrire des scrapers.

PHP, Perl, Python, Ruby… que choisir ?

[modifier | modifier le wikicode]

Nous allons voir les qualités et les défauts de chacun d'eux. N'oubliez pas que langage le plus adapté est sûrement celui que vous connaissez déjà !

Paquet logiciel

PHP se prête bien au jeu, surtout depuis que PHP est prévu pour pouvoir être utilisé en ligne de commande (et pas seulement en script côté serveur comme c'est sa fonction originelle).

Il faudra toutefois lui adjoindre de nombreuses extensions pour pouvoir travailler correctement car nombre des fonctionnalités que nous allons utiliser ne sont pas fournies nativement. Au fur et à mesure, nous vous indiquerons comment fournir à PHP les éléments nécessaires à l'exécution du code fournit. Il pourra s'agir d'utiliser PEAR, PECL, ou le gestionnaire de paquet pour étendre PHP. Aussi, assurez-vous d'avoir un peu manipulé ces outils.

Quelques ressources :

Scrapy (framework Python)

scRUBYt! (framework Ruby)

Les autres langages

[modifier | modifier le wikicode]

Si vous souhaitez utiliser JavaScript, vous serez aidé par l'utilisation de GreaseMonkey.

Vous pouvez intégrer un script Web Harvest dans une application Java[3].

Un processus en deux étapes

[modifier | modifier le wikicode]
  1. récupération des contenus bruts
  2. analyse des données brutes

Récupération

[modifier | modifier le wikicode]

Nous allons voir comment récupérer les données brutes qui nous intéresse. Vous devez garder à l'esprit, tout au long de vos travaux de développer et de tests, qu'il faut essayer de simuler au plus près le comportement du navigateur manipulé par un utilisateur lambda. Il faut que le serveur Web n'y voit que du feu.

Comme nous allons le voir, il peut s'agir de cas très simples (une page unique, accessible publiquement via son URL) à des cas très complexes (plusieurs pages, authentification nécessaire, cookies, CAPTCHA, filtres divers). Nous verrons que le gros du travail pour répondre à ces problématiques consiste en la manipulation des requêtes HTTP que nous enverrons au serveur. Aussi, nous rappellerons les notions essentielles de ce protocole et nous vous invitons à vous documenter plus en profondeur sur celui-ci si nécessaire.

Le fonctionnement d'HTTP

[modifier | modifier le wikicode]

Il ne s'agit pas là de donner une référence exhaustive de ce protocole mais les bases nécessaires à la compréhension de la suite.

Pour manipuler des requêtes HTTP en PHP. Vous avez plusieurs solutions :

Obtenir une page simple

[modifier | modifier le wikicode]

Ceci représente le cas le plus simple. Il s'agit d'obtenir une page disponible simplement en chargeant l'URL. Aucune étape préalable n'est requise.

<?php
$url = 'http://wikilivres.wordpress.com/';
$contents = file_get_contents($url);
echo $contents; // affichera le code HTML de la page
?>

file_get_contents renverra le code HTML de le page dont l'URL est donnée. Notez que fournir directement une URL peut être interdit par certaines directives de configuration (voir le manuel).

Cette première méthode fait le travail. Toutefois, nous avons vu que nous serons amenés à manipuler les requêtes HTTP. Aussi, mettons-nous le pied à l'étrier en commençant tout de suite. Nous utiliserons la bibliothèque PEAR::HTTP_Client : n'oubliez pas d'installer cette bibliothèque à l'aide de pear :

pear install HTTP_Client

Voici un exemple d'utilisation le plus simple de cette bibliothèque.

<?php
require_once "HTTP/Request.php";

$url = 'http://wikilivres.wordpress.com/';

// on crée une nouvelle requête http vers $url
$requete = new HTTP_Request($url); 
// sans préciser de paramètres supplémentaires on envoie la requête au serveur
$requete->sendRequest();
// on peut maintenant voir la réponse du serveur
echo $requete->getResponseBody(); // affichera le code HTML de la page $url
?>

Ce code aura un comportement équivalent au code précédent.

Vous pouvez utiliser open-uri. Vous récupérez avec open() un objet que vous pouvez manipuler comme File

require 'open-uri'

url = 'http://wikilivres.wordpress.com/'

# on charge l'URL
page = open url

# on peut lire page comme un fichier
puts page.read # affiche le contenu de la page

Comme nous l'avons expliqué, nous aurons besoin de manipuler des requêtes HTTP plus complexes pour arriver à nos fins. Pour cela, vous pouvez utiliser la bibliothèque net/http.

require 'net/http'
require 'uri'

# On crée d'abord un objet URI pour simplifier
url = URI.parse('http://wikilivres.wordpress.com/')

# get renvoie directement le contenu HTML de la page
puts Net::HTTP.get(url)

# pour avoir les détailes de la réponse, on utilise plutôt get_response
reponse = Net::HTTP.get_response(url)

puts reponse.body # affiche le contenu HTML de la page

# reponse est un objet de type Net::HTTPResponse
# plus exactement, c'est une instance d'une classe fille selon le résultat
# de la requête
reponse.is_a? Net::HTTPOK # vrai si la page est bien trouvée (code 200)

reponse.is_a? Net::HTTPNotFound # vrai si la page n'est pas trouvée (code 404)

# pour récupérer les valeurs des en-têtes HTTP de la réponse,
# on peut la manipuler comme un tableau associatif
reponse.each_key { | k | puts k }

Contourner les filtres

[modifier | modifier le wikicode]

Le User-Agent sniffing

[modifier | modifier le wikicode]

Wikipédia propose un article sur : « User-Agent ».

À chaque fois que vous

Pour parer cela, vous pouvez recourir à la tromperie (ou « User-Agent spoofing »). Il s'agit de falsifier la valeur User-Agent de la requête HTTP pour faire croire au serveur que le client est celui à quoi il s'attend. Quelques exemples d'User-Agent qui devraient vous permettre de passer les filtres :

Internet Explorer 7 sous Windows Vista
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)
Mozilla Firefox 3 sous Ubuntu Linux
Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9b5) Gecko/2008041514 Firefox/3.0b5
Safari 3 sous Mac OS X
Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; fr-fr) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1
Google Bot
Googlebot/2.1 (+http://www.google.com/bot.html)

Avec Firefox, vous pouvez pratiquer le User-Agent spoofing facilement grâce à l'extension User Agent Switcher

$useragents = array (
	'IE7' => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
	'FF3' => 'Mozilla/5.0 (X11; U; Linux i686; fr; rv:1.9b5) Gecko/2008041514 Firefox/3.0b5',
	'safari' => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_5; fr-fr) AppleWebKit/525.18 (KHTML, like Gecko) Version/3.1.2 Safari/525.20.1',
	'googlebot' => 'Googlebot/2.1 (+http://www.google.com/bot.html)'
);

Vous pouvez, dans votre requête HTTP, pratiquer le User-Agent spoofing :

$requete->addHeader('User-Agent', $useragents['IE7']);

De la même que le User-Agent, à chaque requête est envoyée une donnée qu'on appelle le référant. Il s'agit de l'URL de la page qui comportait le lien vers la page qui est demandée. Cette information est donné dans l'en-tête Referer) de la requête : dans l'hypothèse où la page aurait été demandée directement, ce champ a pour valeur la chaîne vide.

Le filtrage par référant consiste à vérifier, lorsqu'une page est demandée, que la page référante est cohérente avec l'organisation du site. Notamment, cette technique est utilisée pour éviter le téléchargement massif d'images, Avant d'envoyer l'image en réponse à la requête, le serveur vérifie que l'adresse référante est bien une page du site (et pas une page d'un autre site, pour éviter) voire une page de l'album qui inclue l'image. Se ce n'est pas le cas, le serveur, au lieu d'envoyer l'image en réponse, renvoie un code d'erreur.

Pour contrer cette technique, on peut, comme avec l'User-Agent, tromper le serveur est manipulant l'en-tête de la requête et en y écrivant, en dur, l'adresse à laquelle il s'attend. Une méthode simple est de stocker systématiquement à chaque fois que votre programme trouve une URL à exploiter, l'URL qu'il faudra fournir comme référant. Vous pouvez utiliser un tableau associatif de la forme URL → URL référant.

De même, vous pouvez renseigner un referer arbitraire :

$requete->addHeader('Referer', $urlreferer);
Un exemple de test de type CAPTCHA. Il faudra rentrer « following finding » dans le champ du formulaire pour passer le test. Vous pouvez trouver d'autres exemples dans la catégorie « Captcha » sur Commons

Les CAPTCHA sont des petits tests que l'on fait passer via un formulaire. Il s'agit de poser une question à laquelle seule un être humain peut répondre (et pas une machine). La plupart du temps, on donne une image et on demande à la personne de recopier le texte que l'image comporte. Le texte de l'image est volontairement transformé de multiples façons pour rendre toute reconnaissance automatique de caractères inopérante.

Le défaut de ce système, c'est qu'il est parfaitement inaccessible aux personnes atteintes de déficiences visuelles[4].

Vous souhaiterez peut-être réaliser un script devant passer un CAPTCHA, or ces tests sont faits justement pour vous en empêcher. Aussi, bien qu'il soit possible de casser un CAPTCHA (certains sont mal conçus et peuvent être décodés[5], notamment avec des algorithmes de reconnaissances de formes. La casse de CAPTCHA est un sujet trop vaste et complexe pour être abordé ici), la solution la plus simple reste de demander à l'utilisateur de votre script de passer le test à la place de votre programme. Vous pouvez par exemple télécharger l'image et demander à l'utilisateur de l'ouvrir avec son logiciel habituel puis de rentrer le code.

Gérer les cookies

[modifier | modifier le wikicode]

Toujours afin de mimer le comportement du navigateur, vous aurez besoin de gérer les cookies.

La bibliothèque PEAR::HTTP_Client intègre un gestionnaire de cookies.

// Avant de la faire la requête, on crée une nouvelle session
$cookies = new HTTP_Client_CookieManager();

// on lance la requête normalement
$requete->sendRequest();

// On prend en compte les demandes d'enregistrement de cookies
$cookies->updateCookies($requete);

// À la prochaine requête, on pourra fournir les cookies
$cookies->passCookies($une_autre_requete);
$une_autre_requete->sendRequest();

Remplir et valider des formulaires

[modifier | modifier le wikicode]

formulaire HTML

Typiquement, un formulaire d'identification ressemble à ça (nous avons omis les multiples balises qui servent à la mise en forme, elles peuvent être ignorées étant donné qu'elles n'affectent pas le déroulement des choses).

<form action="validation.php" method="POST">
	Identifiant : <input type="text" name="identifiant">
	Mot de passe : <input type="password" name="motdepasse">
	<input type="submit" value="Valider">
</form>

Pour passer le formulaire, il faudra envoyer la requête à l'URL donnée dans l'attribut action de l'élément <form>.

Les données seront envoyées dans la requête sous la forme d'une chaîne de caractères. Cette chaîne est formée de la suite des couples identifiant=valeur séparés par des &. Les identifiants sont dans les attributs name des différents champs du formulaire (attention, l'attribut name ne doit pas être confondu avec l'éventuel attribut id). Par exemple, si les données à renseigner sont « dudule » pour le champ identifiant et « 8D4g9h » pour le champ motdepasse. La chaîne sera identifiant=dudule&motdepasse=8D4g9h

Avant d'envoyer la requête, vous devez la préparer pour simuler l'entrée des données dans le formulaire. Pour cela, vous devez regarder le contenu de l'attribut method de l'élément <form>. Il ne peut s'agir que de POST ou de GET.

Dans le cas de POST, ?.

Dans le cas de GET, la chaîne est ajoutée à l'URL après ?. Ainsi, il suffira, pour valider le formulaire, d'envoyer la requête à http://example.org/le/chemin/de/la/page/validation.php?identifiant=dudule&motdepasse=8D4g9h

Pour mieux comprendre, vous pouvez essayer de vous identifier sur un site et d'examiner le contenu des requêtes HTTP. En particulier, ce sera utile pour les formulaires complexes pour que vous compreniez la forme des données selon les différents types de champs.

Si votre programme échoue, assurez-vous de fournir un en-tête complet : c'est à dire d'avoir renseigné tous les champs du formulaire (même avec des valeurs vides, fausses, en dur), y compris les champs de type hidden s'il y en a. Essayez de valider le formulaire avec votre navigateur et examinez la requête. Assurez vous que votre programme envoie bien toutes ces informations (les requêtes envoyés par votre programme doivent être le plus proche possible de celles envoyées par la navigateur).

Dans le cas de GET :

Dans le cas de POST :

// D'abord, on précise que la requête est de type POST
$requete->setMethod(HTTP_REQUEST_METHOD_POST);

// on ajoute les données
$requete->addPostData('identifiant','dudule');
$requete->addPostData('motdepasse','8D4g9h');

HTML sale

Utiliser les expressions régulières

[modifier | modifier le wikicode]

Les expressions régulières sont un outils très puissants. Leur principale qualité est qu'elles n'ont pas besoin que le code soit du XML ou qu'il soit valide. Elles permettent de faire du quick and dirty, et, en pratique, elles seront très utilisées.

PHP propose nativement PCRE, expressions rationnelles compatible Perl.

Manipuler des URLs

[modifier | modifier le wikicode]
À faire...link={{{link}}}

quid du passage d'un chemin relatif à un adresse absolue ?

  • Coder et décoder une URL
  • Décomposer une URL
  • Composer une URL

PHP fournit nativement un ensemble de fonctions pour manipuler les URLs. Cela peut être complété par quelques fonctions sur les fichiers.

Coder et décoder une URL

[modifier | modifier le wikicode]

Les fonctions urlencode et urldecode permettent d'encoder et de décoder une URL sous forme de chaîne de caractères. En particulier, c'est urlencore qu'il vous faudra utiliser lorsque vous encoderez des URL pour remplir des formulaires.

$url = 'http://www.example.org/chemin/vers/une_ressource.ext?cle1=valeur1&cle2=valeur2#ancre';
$coded_url = urlencode($url);
echo $coded_url;

affiche :

http%3A%2F%2Fwww.example.org%2Fchemin%2Fvers%2Fune_ressource.ext%3Fcle1%3Dvaleur1%26cle2%3Dvaleur2%23ancre

Pour l'opération inverse :

echo urldecode($coded_url); // affiche une chaîne identique à $url

Décomposer une URL

[modifier | modifier le wikicode]
$url = 'http://www.example.org/chemin/vers/une_ressource.ext?cle1=valeur1&cle2=valeur2#ancre';
$url_infos = parse_url($url);
print_r($url_infos);

parse_url peut déjà vous permettre d'éclater une URL complète en ses différentes composantes. Voilà le tableau produit :

Array
(
    [scheme] => http
    [host] => www.example.org
    [path] => /chemin/vers/une_ressource.ext
    [query] => cle1=valeur1&cle2=valeur2
    [fragment] => ancre
)

Ensuite, pour le chemin (path), vous pouvez utiliser pathinfo pour décomposer le chemin :

// $url_infos['path'] vaut "/chemin/vers/une_ressource.ext" (voir ci-dessus)
print_r(pathinfo($url_infos['path']));

Là aussi, un tableau associatif donne les différentes parties :

Array
(
    [dirname] => /chemin/vers
    [basename] => une_ressource.ext
    [extension] => ext
    [filename] => une_ressource
)

Notons l'existence des fonctions dirname et basename qui vous permettront, étant donné un chemin, d'accéder directement et respectivement au répertoire (comme [dirname]) et au nom du fichier (comme [basename]) : il s'agit simplement de raccourci d'écriture.

Pour la partie query, on peut utiliser parse_str :

// $url_infos['query'] vaut "cle1=valeur1&cle2=valeur2" (voir ci-dessus)
// $query n'existe pas encore
parse_str($url_infos['query'], $query);
print_r($query);

Qui, dans notre exemple, donne le tableau associatif :

Array
(
    [cle1] => valeur1
    [cle2] => valeur2
)

Composer une URL

[modifier | modifier le wikicode]

Pour la partie query, on peut faire usage de http_build_query.

Obtenir du XHTML valide

[modifier | modifier le wikicode]

Nous l'avons vu, il y a des chances pour que les pages brutes que vous obteniez soit en HTML et non en XHTML et qu'en plus de ça il se peut que ce ne soit pas des pages valides, c'est à dire que le code peut comporter des erreurs (balises non fermées, etc.). Or, si vous souhaitez pouvoir utiliser les outils XML (XPath, XQuery, XSLT), il sera nécessaire de corriger les erreurs de la page pour que ce soit du code XML valide.

Pour nettoyer du code, la première chose à faire est de faire appel à un outil de nettoyage, tel que Tidy par exemple. Cette première passe fera déjà le gros du travail. Lorsque vous développerez votre script, passez le résultat de Tidy au validateur W3C. Éventuellement, vous verrez qu'il peut rester quelques erreurs même après le passage de Tidy. Vous devez alors écrire des correctifs ad-hoc. En général, un usage simple des expressions régulières suffiront.

Le validateur peut aussi vous donner quelques erreurs qui peuvent être ignorées quand on souhaite obtenir simplement du XML. Par exemple, le fait que l'attribut alt de l'élément <img> ne soit pas renseigné est interdit par les règles du HTML, néanmois s'il n'est pas renseigné, le code reste du XML correct.

...Donner plus d'exemples...

Paquet logiciel

Il vous faudra peut-être faire quelques manipulations pour avoir bibliothèque Tidy de PHP. La fonction tidy_repair_string peut être utilisée.

$url = 'http://www.flickr.com/search/?q=fun';
$contents = file_get_contents($url);

// nettoyage du code
$contents = tidy_repair_string($contents);

Si vous souhaitez utiliser l'API DOM de PHP par la suite, il ne sera pas nécessaire d'avoir un code valide W3C. Aussi, vous pouvez utiliser l'API pour générer la liste des erreurs qu'il faudrait corriger avant de travailler sur le document avec DOM.

/* Directement à la suite du code ci-dessus */
$doc = new DOMDocument();
$doc->loadHTML($contents); // Cette ligne va générer des messages d'erreur de type Warning

Un exemple partiel de la série de Warning qui peut être générée :

Warning: DOMDocument::loadHTML(): Tag nobr invalid in Entity, line: 428
...
Warning: DOMDocument::loadHTML(): ID a_link_to_map already defined in Entity, line: 743
...

Ne vous laissez pas impressionner par la quantité de ces Warning qui surgiront. La plupart du temps ce sont toujours les même erreurs qui reviennent à différents endroits. Voyez comment en corriger une et écrivez (avec les expressions régulières) des correctifs pour toutes les erreurs de même type.

Notez qu'il ne s'agit que de Warning et que les données sont quand même chargées et peuvent être manipulées. Aussi, vous pouvez choisir d'ignorer ces avertissements ou estimer que vos correctifs sont suffisant. Pour ne plus afficher ces messages d'erreurs, utilisez simplement l'opérateur de contrôle d'erreur @ :

@$doc->loadHTML($contents); // Les messages d'erreur de type Warning seront ignorés avec le '@'

Une fois que vous serez parvenu à obtenir les différentes URL des fichiers qu'il faut télécharger (pour en avoir une copie locale), vous souhaiterez sûrement vous lancer dans le téléchargement effectif.

Paquet logiciel

Vous pouvez utiliser la bibliothèque cURL de PHP

$url_fichier = 'http://upload.wikimedia.org/wikipedia/commons/2/22/New_York_City_at_night_HDR.jpg';

// on récupère le nom du fichier
$nom_fichier = basename(parse_url($url_fichier,PHP_URL_PATH)); // ici "New_York_City_at_night_HDR.jpg"

$fp = fopen ($nom_fichier, 'w+');

// initialisation de la session
$ch = curl_init($url_fichier);

// on configure cURL pour que les données téléchargées soient écrites dans le fichier
curl_setopt($ch, CURLOPT_FILE, $fp);

// on lance le téléchargement
echo "Téléchargement de $nom_fichier...";
curl_exec($ch);
echo "OK\n";

// le téléchargement est terminé, on ferme tout
curl_close($ch);
fclose($fp);

Contourner les filtres

[modifier | modifier le wikicode]

Grâce à curl_setopt, vous pourrez configurer cURL pour contourner les filtres dont nous avons parlé plus tôt. Il suffira d'ajouter au script précédent (vers la ligne 13) :

curl_setopt($ch,CURLOPT_REFERER,$url_referer);
curl_setopt($ch,CURLOPT_USERAGENT,$useragents['IE7']);

curl_setopt vous permettra également de manipuler les cookies si besoin est.

Manipuler du contenu Flash

[modifier | modifier le wikicode]

Conseils pour développer des scripts

[modifier | modifier le wikicode]

Nous avons étudier les aspects techniques qui vous permettront de vous en sortir. Maintenant, voici quelques conseils pratiques.

Étudiez l'existant

[modifier | modifier le wikicode]

Nous fournissons dans un des chapitres des liens vers des scripts fonctionnels. La plupart du temps, il s'agit de logiciels libres. Vous pouvez donc obtenir leur code source et étudier leur fonctionnement.

Dans votre travail, vous pourrez peut-être prendre appui sur une bibliothèque ou un framework spécifique au site auquel vous vous attaquez. Quelques exemples :

Avant de vous plonger dans ce livre, vous aviez sûrement déjà une ou plusieurs idées derrière la tête. Vous pouvez vous attaquer aux sites que vous ciblés pour commencer. Si toutefois ce n'était pas le cas. Vous pouvez vous exercez sur les différents CMS :

  • Un moteur de blog (Dotclear ou Wordpress) : créer un flux Atom complet peut être utile, certains blogs sont configurés pour ne proposer que des flux partiels)
  • Un moteur de galerie d'image (Gallery, ZenPhoto) : extraire toutes les images en respectant l'arborescence des albums en créant des dossier équivalents.

Vous pouvez aussi vous attaquer à un site populaire : c'est à dire, un site dont on peut supposer que la publication d'un scraper ferait des heureux…

Faites des tests

[modifier | modifier le wikicode]

Ne vous fiez pas à votre navigateur

[modifier | modifier le wikicode]

Partagez vos créations

[modifier | modifier le wikicode]

La modèle du logiciel libre est tout à fait adapté à de tels scripts. Aussi, n'hésitez pas à publier vos scripts sur une forge et à fédérer les utilisateurs qui pourront remonter les bugs et les contributeurs qui pourront vous aider à maintenir votre script fonctionnel.

Pour cela, n'hésitez pas à ajouter, dans votre script, un petit message d'invitation vers le site. En particulier, si le script échoue (ce que vous ne manquerez pas de détecter), invitez l'utilisateur à se rendre sur le site pour télécharger et essayer une version plus récente et, si cela ne fonctionne toujours pas, à signaler le bug sur la forge, dans un forum ou par courriel. Vous avez tout à y gagner !

Citons l'auteur de youtube-dl : « Le temps passa, il y eu plus d'utilisateurs et beaucoup d'entre eux m'écrivirent au sujet des améliorations possibles et rapportèrent des bugs. C'est le bon côté d'avoir beaucoup d'utilisateurs. Je ne l'utilise pas tant que ça, mais quand YouTube change quelque-chose et que cela casse mon programme, cela m'est immédiatement signalé par quelques personnes et cela peut être corrigé en moins de 24 heures. »[6]

Vérifiez la bonne configuration chez l'utilisateur

[modifier | modifier le wikicode]

Il est très frustrant de se retrouver face à un message d'erreur incompréhensible pour un non-initié. Pourtant on peut souvent vérifier les possibilités de l'utilisateur et sortir en cas de problème en donnant les éléments permettant de résoudre le problème.

Par exemple, on peut vérifier qu'une bibliothèque (ici cURL) est bien installée.

if (!function_exists('curl_init'))
	die("ERREUR : la bibliothèque cURL pour PHP n'est pas installée
Installez-la et réessayez à nouveau\n");

Rendez votre script un minimum modulaire

[modifier | modifier le wikicode]

Récupérez à la volée des informations supplémentaires.

Votre script dont fonctionner sans passer de paramètres en ligne de commande. Néanmoins, permettez de modifier le comportement du script de façon à moduler un peu l'usage qui peut en être fait.

PHP ne permet pas de gérer simplement les arguments de la ligne de commande. Néanmoins, il existe des bibliothèques PEAR qui rendent la chose très simple.

Un peu de fioriture

[modifier | modifier le wikicode]

Ressources externes

[modifier | modifier le wikicode]




  1. http://www.virusphoto.com/41588-important-au-sujet-des-blogs.html
  2. Pour vous aider dans votre adaptation, vous pouvez vous appuyer sur ce guide d'équivalence entre les extensions Firefox et Opéra (il n'a toutefois pas été mis à jour récemment)
  3. Voir la section « Java code usage » de la page « Usage » de Web Harvest
  4. Voir anglais « Inaccessibility of CAPTCHA » publié par le W3C (organisme qui régit les standards du Web, notamment en matière d'accessibilité) ou sa traduction : « L'inaccessibilité des CAPTCHA »
  5. voir l'étude « PWNtcha » ou l'étude « Breaking a Visual CAPTCHA » qui montre que de nombreux systèmes de CAPTCHA peuvent être cassés. Remarquons que les technologies de CAPTCHA et celles de casse évoluent constamment.
  6. « As time passed, it had more users and many of them wrote me about possible improvements and reported bugs. That’s the great thing of having many users. I don’t use it that much, but when YouTube changes something and my program breaks, I inmediately get a couple of people complaining by email, and it can be fixed in less than 24 hours. » : article youtube-dl is dead, long life to… youtube-dl du blog de l'auteur de youtube-dl

http://www.example.org/un/dossier/un_fichier.ext?cle1=valeur1&cle2=valeur2#ancre

Il existe de nombreux outils spécialisés dans l'extraction de contenus Web. Vous pourrez trouver un comparatif de ces outils sur Wikipedia.

Web Harvest est l'un d'entre eux : il est libre et distribué gratuitement.

Obtenir, installer et configurer Web Harvest

[modifier | modifier le wikicode]

Vous pouvez l'obtenir en le téléchargeant depuis le site officiel.

Pour le faire fonctionner, il vous faudra une machine virtuelle Java.

La première chose à faire lorsque vous lancerez Web Harvest pour la première fois est de configurer le répertoire de sortie. C'est dans ce dossier que vous trouverez les images, fichiers, liens qui seront extraits à l'aide de Web Harvest. Pour cela, rendez vous dans le menu « Execution → Settings » et réglez « Output path ».